// import "@/lib/audio.js";
// #ifdef H5
import "@/lib/socket.io.js";
// #endif

// #ifdef MP-WEIXIN
import * as io from "@/lib/socket.io.js";
// #endif

import { SingletonFactory } from "./single";
import { socketLogin, socketTTS } from "@/api/socket";

declare global {
  interface Window {
    /** SpeechSDK */
    SpeechSDK: Record<string, any>;
    io: Record<string, any>;
  }
}
const EventType = [
  "login_status",
  "tts_start",
  "tts",
  "image",
  "image_progress",
  "chat_text",
  "chat_audio",
  "chat_text_end",
  "chat_audio_end",
  "chat_product",
  "shop",
  "playing"
] as const;
type E = (typeof EventType)[number];

export default class Lnkyeah extends SingletonFactory<Lnkyeah>() {
  public socket: any;
  static data: any;
  private loadingAudio: boolean = false;
  private event: Partial<Record<E, Function[]>> = {};
  private $onceEvent: Partial<Record<E, Function[]>> = {};

  private onceEmit(event: E, value: any) {
    const e = this.$onceEvent[event];
    if (e) {
      for (let i = 0; i < e.length; i++) {
        e[i](value);
        e.splice(i, 1);
      }
    }
  }
  static setData(data: any) {
    this.data = data;
  }
  async init(options: {
    loginResult?: (err: boolean) => void;
    connect?: () => void;
    chatText?: (e: string) => void;
    chatTextEnd?: (e: string) => void;
  }) {
    if (!Lnkyeah.instance.socket?.active) {
      options.connect?.();
      const result = await Lnkyeah.instance.login();
      options.loginResult?.(result);
    }
    if (options.chatText) {
      Lnkyeah.instance.on("chat_text", options.chatText);
    }
    if (options.chatTextEnd) {
      Lnkyeah.instance.on("chat_text_end", options.chatTextEnd);
    }
  }
  login(): Promise<boolean> {
    return new Promise(resolve => {
      // this.socket = window.io.connect("https://engine-robot.lnkyeah.com");
      this.socket = io("https://engine-robot.lnkyeah.com", {
        query: {},
        transports: ["websocket", "polling"],
        timeout: 5000
      });

      this.socket.on("login", async () => {
        const [err, data] = await socketLogin();
        if (!err) {
          this.socket.emit("login", { token: data.data.socket_token });
          resolve(true);
        } else {
          this.socket.close();
          resolve(false);
        }
      });
    });
  }

  closeSocket() {
    if (this.socket) {
      this.socket.close();
    }
  }
  once(event: E, callback: Function) {
    if (this.$onceEvent[event]) {
      this.$onceEvent[event]?.push(callback);
    } else {
      this.$onceEvent[event] = [callback];
    }
  }
  off(event: E) {
    if (this.event[event]) {
      delete this.event[event];
    }
  }
  on(event: E, callback: Function) {
    if (this.event[event]) {
      this.event[event]?.push(callback);
    } else {
      this.event[event] = [callback];
    }
  }
  emit(event: E, value: any) {
    const e = this.event[event];
    if (e) {
      for (let i = 0; i < e.length; i++) {
        e[i](value);
      }
    }
  }
  async getVoice(message: string) {
    try {
      if (this.loadingAudio) {
        uni.showToast({
          title: "正在获取声音",
          icon: "none"
        });
        return;
      }
      await socketTTS(message);
      this.loadingAudio = false;
    } catch (err) {
      this.loadingAudio = false;
    }
  }
}
